package com.hospital.register.core.repository.impl;

import com.hospital.register.constants.BaseEntityConstants;
import com.hospital.register.constants.HospitalConstants;
import com.hospital.register.core.repository.HospitalRepository;
import com.hospital.register.dto.core.common.HospitalPageDto;
import com.hospital.register.model.core.Hospital;
import com.hospital.register.vo.core.common.HospitalQueryVo;
import com.hospital.register.vo.core.admin.HospitalPageVo;
import com.mongodb.client.result.UpdateResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;

import java.util.Date;
import java.util.List;

@Repository
public class HospitalRepositoryImpl implements HospitalRepository {

    /**
     * 访问 Mongo
     */
    @Autowired
    private MongoTemplate mongoTemplate;


    @Override
    public boolean insert(Hospital hospital) {
        return this.mongoTemplate.insert(hospital) != null;
    }

    @Override
    public boolean updateByHosCode(Hospital hospital) {
        Criteria criteria = Criteria.where(HospitalConstants.HOSCODE).is(hospital.getHoscode())
                .and(BaseEntityConstants.FIELD_IS_DELETED).is(BaseEntityConstants.NOT_DELETED);
        Query query = Query.query(criteria);

        Update update = Update.update(HospitalConstants.HOSNAME, hospital.getHosname())//名称
                .set(HospitalConstants.HOSTYPE, hospital.getHostype())//类型
                .set(HospitalConstants.PROVINCE_CODE, hospital.getProvinceCode())//省
                .set(HospitalConstants.CITY_CODE, hospital.getCityCode())//市
                .set(HospitalConstants.DISTRICT_CODE, hospital.getDistrictCode())//区
                .set(HospitalConstants.ADDRESS, hospital.getAddress())//详细地址
                .set(HospitalConstants.LOGO_DATA, hospital.getLogoData())//logo
                .set(HospitalConstants.INTRO, hospital.getIntro())//介绍
                .set(HospitalConstants.ROUTE, hospital.getRoute())//路线
                .set(HospitalConstants.STATUS, hospital.getStatus())//状态
                .set(HospitalConstants.BOOKING_RULE, hospital.getBookingRule())//预约规则
                .set(BaseEntityConstants.UPDATE_TIME, hospital.getUpdateTime());

        UpdateResult updateResult = this.mongoTemplate.updateFirst(query, update, Hospital.class);
        return updateResult.wasAcknowledged();
    }

    @Override
    public boolean existsByHoscode(String hoscode) {
        Criteria criteria = Criteria.where(HospitalConstants.HOSCODE).is(hoscode)
                .and(BaseEntityConstants.FIELD_IS_DELETED).is(BaseEntityConstants.NOT_DELETED);
        Query query = Query.query(criteria);
        return this.mongoTemplate.count(query, Hospital.class) == 1L;
    }

    @Override
    public HospitalQueryVo findByHoscode(String hoscode) {
        Criteria criteria = Criteria.where(HospitalConstants.HOSCODE).is(hoscode)
                .and(BaseEntityConstants.FIELD_IS_DELETED).is(BaseEntityConstants.NOT_DELETED);
        Query query = Query.query(criteria);
        return this.mongoTemplate.findOne(query, HospitalQueryVo.class, HospitalConstants.COLLECTION_NAME);
    }

    @Override
    public Page<HospitalPageVo> findPage(HospitalPageDto dto) {
        Criteria criteria = new Criteria();

        if (dto.getHoscode() != null && dto.getHoscode().length() > 0) {//医院编号
            criteria.and(HospitalConstants.HOSCODE).is(dto.getHoscode());
        }

        if (dto.getHostype() != null && dto.getHostype().length() > 0) {//医院类型
            criteria.and(HospitalConstants.HOSTYPE).is(dto.getHostype());
        }

        if (dto.getProvinceCode() != null && dto.getProvinceCode().length() > 0) {//所在省编号
            criteria.and(HospitalConstants.PROVINCE_CODE).is(dto.getProvinceCode());
        }

        if (dto.getCityCode() != null && dto.getCityCode().length() > 0) {//所在市编号
            criteria.and(HospitalConstants.CITY_CODE).is(dto.getCityCode());
        }

        if (dto.getDistrictCode() != null && dto.getDistrictCode().length() > 0) {//所在区
            criteria.and(HospitalConstants.DISTRICT_CODE).is(dto.getDistrictCode());
        }

        if (dto.getStatus() != null) {//状态
            criteria.and(HospitalConstants.STATUS).is(dto.getStatus());
        }

        if (dto.getHosname() != null && dto.getHosname().length() > 0) {//名称不为空
            criteria.and(HospitalConstants.HOSNAME).regex(dto.getHosname());
        }

        criteria.and(BaseEntityConstants.FIELD_IS_DELETED).is(BaseEntityConstants.NOT_DELETED);//未删除
        Query query = Query.query(criteria);
        long total = this.mongoTemplate.count(query, HospitalConstants.COLLECTION_NAME);

        Pageable pageable = PageRequest.of(dto.getPage() - 1, dto.getLimit());
        query.with(pageable);

        List<HospitalPageVo> vos = this.mongoTemplate.find(query, HospitalPageVo.class, HospitalConstants.COLLECTION_NAME);
        Page<HospitalPageVo> page = new PageImpl<>(vos, pageable, total);

        return page;
    }

    @Override
    public boolean updateStatusById(String id, Byte status) {
        Criteria criteria = Criteria.where(BaseEntityConstants.ID).is(id)//id
                .and(BaseEntityConstants.FIELD_IS_DELETED).is(BaseEntityConstants.NOT_DELETED);//未删除
        Query query = Query.query(criteria);

        //通过下面这种方式更新，匹配不到结果
//        Update update = Update.update(HospitalConstants.STATUS, status)
//                .set(BaseEntityConstants.UPDATE_TIME, new Date());
//        UpdateResult updateResult = this.mongoTemplate.updateFirst(query, update, HospitalConstants.COLLECTION_NAME);
//        return updateResult.wasAcknowledged();

        Hospital newHospital = this.mongoTemplate.findOne(query, Hospital.class);
        if (newHospital == null) {
            return false;
        }

        newHospital.setId(id);
        newHospital.setStatus(status);
        newHospital.setUpdateTime(new Date());
        newHospital = this.mongoTemplate.save(newHospital);
        return newHospital != null;
    }

    @Override
    public HospitalQueryVo findById(String id) {
        return this.mongoTemplate.findById(id, HospitalQueryVo.class, HospitalConstants.COLLECTION_NAME);
    }

}
